<?php

/**
 * User password recovery model
 *
 */
class Application_Model_UserRecover
{

    const PRIVATE_KEY='private recovery key';
    
    /**
     * Send user password recovery confirmation message
     *
     * @param object $user
     */
    static function sendRecoveryMessage(Application_Model_User $user)
    {
        $message=Zend_Registry::get('locale')->_('Hello').' '.$user.' !'."\n\n";
        $message.=Zend_Registry::get('locale')->_('You have requested password recovery at').' '.$_SERVER['HTTP_HOST']."\n";
        $message.=Zend_Registry::get('locale')->_('To reset your password, please follow the link below')."\n\n";
        $message.=self::generateRecoveryUrl($user);

        $mail = new Zend_Mail('UTF-8');
        $mail->setHeaderEncoding(Zend_Mime::ENCODING_BASE64);
        $mail->setBodyText($message);
        $mail->setFrom('noreply@'.$_SERVER['HTTP_HOST'], ucwords($_SERVER['HTTP_HOST']));
        $mail->addTo($user->email, !empty($user->nicename) ? $user->nicename : $user->login);
        $mail->setSubject(Zend_Registry::get('locale')->_('Password recovery'));
        $mail->send();
    }
    
    /**
     * Returns recovery URL
     *
     * @param object $user
     * @return string
     */
    static function generateRecoveryUrl(&$user)
    {
        $url=Zend_Registry::get('view')->siteUrl().Zend_Registry::get('view')->fixUrl('user/recover/'.self::generateRecoveryHash($user));
        
        return $url;
    }
    
    /**
     * Returns recovery hash
     *
     * @param object $user
     * @return string
     */
    static function generateRecoveryHash(&$user)
    {
        return $user->id.':'.md5((!empty($user->meta['user_key']) ? $user->meta['user_key'] : $user->id.$user->login).self::PRIVATE_KEY);
    }
    
    /**
     * Returns an associative array with user data
     *
     * @param string $key
     * @return array
     */
    static function parseRecoveryHash($key)
    {
        if (!strpos($key,':')) return false;
        
        $data=explode(':',$key);
        
        return array(
            'uid' => $data[0],
            'hash' => $data[0].':'.$data[1]
        );
    }
    
    /**
     * Checks if recovery key matches or not
     * Resets user password if valid
     *
     * @param string $key
     */
    static function do_recover($key)
    {
        $data=self::parseRecoveryHash($key);
        
        if (is_array($data))
        {
            $userTbl=new Application_Model_UserDb();
             
            $user=$userTbl->fetchUserById($data['uid']);
            
            if ($user->isRegistered())
            {
                $hash=self::generateRecoveryHash($user);

                if ($hash == $data['hash'])
                {
                    $password=self::randomChars();
                    $user->password=Application_Model_User::crypt_password($password);
                    
                    $userTbl->save($user);
                    
                    self::sendPasswordMessage($user,$password);
                    
                    return true;
                }
            }
        }
        
        return false;
    }
    
    /**
     * Returns a string with random chars
     *
     * @param int $count
     * @return string
     */
    static function randomChars($count=12)
    {
        $random='';
        
        $chars=range('a','z');
        $chars=array_merge($chars,range('A','Z'));
        $chars=array_merge($chars,range(0,9));
        
        while (strlen($random)<$count)
        {
            $random.=$chars[mt_rand(0,count($chars)-1)];
        }
        
        return $random;
    }
    
     /**
     * Send message with user new password
     *
     * @param object $user
     */
    static function sendPasswordMessage(Application_Model_User $user,$password)
    {
        $message=Zend_Registry::get('locale')->_('Hello').' '.$user.' !'."\n\n";
        $message.=Zend_Registry::get('locale')->_('You have requested password recovery at').' '.$_SERVER['HTTP_HOST']."\n\n";
        $message.=Zend_Registry::get('locale')->_('Your new password').': '.$password."\n\n";
       
        $mail = new Zend_Mail('UTF-8');
        $mail->setHeaderEncoding(Zend_Mime::ENCODING_BASE64);
        $mail->setBodyText($message);
        $mail->setFrom('noreply@'.$_SERVER['HTTP_HOST'], ucwords($_SERVER['HTTP_HOST']));
        $mail->addTo($user->email, !empty($user->nicename) ? $user->nicename : $user->login);
        $mail->setSubject(Zend_Registry::get('locale')->_('Your new password'));
        $mail->send();
    }
}

